/*
 * @Desc: ES层，负责 tcp 和 udp 通信,兼容各种协议报文数据
 *       一种通用于各种协议的消息发送接收接口
 *       对 udp 和 tcp socket 的封装，继承全部的QTcpSocket, QUdpSocket, QTcpServer
 * */

#ifndef NZCONNECTION_H
#define NZCONNECTION_H

#include <QTcpServer>
#include <QUdpSocket>
#include <QTcpSocket>
#include <QNetworkInterface>
#include <QObject>
#include <QTimer>

#define ITIME_SENDCMD 200       // 设置连续发送命令给保护的时间间隔

class NZConnection: public QObject
{
    Q_OBJECT

public:
     NZConnection();
     virtual ~NZConnection();

    // 设置所有的通信参数
    void setIPsandPorts(QString tcpServerIP, QString udpServerIP, QString udpPort, QString tcpPort);

    //void setTcpClientIPPort(QString tcpServerIP, QString tcpPort);  //当连接南瑞继保保护的时候，保护作为tcp服务端，设置连接到保护的tcpip 和 port

    // tcp 服务器监听功能
    bool tcpListen();

    // tcp 服务器停止，断开tcp连接
    void stopTcpServer();

    // udp 发送消息功能 ,指定端口和ip地址发送
    void sendUdpMsg(const QString &msg);
    void sendUdpMsg(const QByteArray &msg);

    // tcp 通过socket发送消息功能
    void sendTcpMsg(const QString &msg);
    void sendTcpMsg(const QByteArray &msg);     // 保护需要接收16进制编码字符报文
    void sendTcpMsg(const QStringList &msg);
    void sendTcpMsg(const QByteArrayList &msg);

    // 获取本机ip地址列表
    QStringList getLocalHostIPList();

    // 从连接的tcp socket中取出消息内容
    QString  getDataFromTcpClient();
    QByteArray getDataFromTcp();

    QString getConnectedInfo();

    QList<QTcpSocket*> m_tcpSocketList;         // 当前暂且只考虑一个连接

    bool isHasPendingDatagrams();
    int pendingDatagramSize();
    void readDatagram(QByteArray datagram, QHostAddress &peerAddr,quint16 &peerPort);


private slots:
    void slot_readTcpRecv();
    void slot_udpMsgRecv();     // udp 接收到消息
    void slot_newTcpConnection();
    void slot_sendTcpMsgList();

    //当执行发送命令列表来获取全部感兴趣的信息时候，每次发送都在收到一个报文的后发送下一个
    void slot_sendTcpMsgListNextOne();

signals:
    void sig_sendUDPMsg(QString); // 发送消息内容或者操作错误打印到界面
    void sig_sendTcpMsg(QString);
    void sig_readyReadTcp(QByteArray);       // tcp socket 有消息可读，对客户端的接口
    void sig_readyRadUdp(QByteArray,QString, QString);       // 有 udp 消息可以读, 后两个参数 ip, port
    void sig_newTcpConnection(QString);     // tcp server 有新的连接进入时候通知client

private:
    QString m_udpPort = "1032";         // 设备UDP服务端的port 南自默认1032
    QString m_tcpPort = "1048";         // 南自103协议主站tcp服务端的port默认开1048
    QString m_udpServerIP;              // 本地udp 服务端ip地址
    QString m_tcpServerIP;              // 保护设备 ip 地址

    QTcpSocket *m_tcpServerSocket;        // tcp 服务端与 保护设备进行通信的套接字
    QTcpServer *m_tcpServer;              // 主站作为tcp服务端开启监听被动等待保护来连接
    QUdpSocket *m_udpClientSocket;        // 主站为udp客户端，保护设备为udp服务端，主站向设备1032端口发送udp报文，告诉保护主站的ip地址

    QTimer m_timerSendCmdList; //
    int  m_indexSendCmdList = 0;    // 发送命令队列的序号
    QStringList m_cmdListReadBill;    //读取信息的命令序列
    QByteArrayList m_cmdListReadAllBillInfo;
};

#endif // NZCONNECTION_H
